/*
 * $Id: SecurityServiceImpl.java 29 2007-04-16 23:57:10Z aaron.day $
 */
package org.crazydays.security;


import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import org.crazydays.core.AbstractService;
import org.crazydays.core.data.PolisRight;
import org.crazydays.core.data.PolisUser;

/**
 * SecurityServiceImpl
 */
public class SecurityServiceImpl
	extends AbstractService
	implements ISecurityService
{
	/**
	 * Create criteria that will filter data according to the user's rights.
	 * The clazz must extend PolisData.
	 * 
	 * @param session Session
	 * @param clazz PolisData class
	 * @param right PolisRight
	 * @param user PolisUser
	 * @return Criteria
	 */
	public Criteria createCriteria(Session session, Class clazz,
			PolisRight right, PolisUser user)
	{
		if (session == null) {
			throw new IllegalArgumentException("session == null");
		}
		if (clazz == null) {
			throw new IllegalArgumentException("clazz == null");
		}
		if (right == null) {
			throw new IllegalArgumentException("right == null");
		}
		if (user == null) {
			throw new IllegalArgumentException("user == null");
		}

		// criteria of the class to be loaded
		Criteria criteria = session.createCriteria(clazz);

		// distinct
		criteria = criteria
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		// join to group
		criteria = criteria.createCriteria("acl.aclGroups", "aclGroup",
				Criteria.INNER_JOIN);

		// allowed
		criteria = criteria.add(Restrictions.eq("aclGroup.allow",
				Boolean.TRUE));

		// right
		criteria = criteria.add(Restrictions
				.eq("aclGroup.right", right));

		// group
		criteria = criteria.createCriteria("aclGroup.group", "group",
				Criteria.INNER_JOIN);

		// group <==> user
		criteria = criteria.createCriteria("group.users", "user",
				Criteria.INNER_JOIN);

		// user
		criteria = criteria.add(Restrictions
				.eq("user.id", user.getId()));

		return criteria;
	}
}
